package com.atguigu.tingshu.search.runners;

import com.atguigu.tingshu.search.service.impl.SearchServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;

/**
 * Description:
 * 我们在当前的Runner类中，使用ApplicationRunner和ApplicationContextAware来实现回调
 * 其中我们实现了ApplicationRunner，重写了run方法，当前run方法会在springboot启动过程中执行
 * 然后我们实现了ApplicationContextAware，重写了setApplicationContext方法，
 * setApplicationContext方法会在springboot启动过程中执行，并且会传入一个ApplicationContext对象
 * 【我们的run方法和setApplicationContext方法都是SpringBoot启动过程中执行的】
 * 这样一来我们当前Runner类的思路就很清晰了
 * 1.我们通过setApplicationContext方法来获取到ApplicationContext对象，即SpringBoot的IOC容器对象
 * 2.然后我们获取到了ioc容器对象，我们通过ioc容器对象获取到我们初始化布隆过滤器需要用到的Bean对象
 * 3.我们通过ioc容器获取到SearchServiceImpl这个Bean对象，以及RBloomFilter这个Bean对象
 * 4.然后我们通过run方法执行布隆过滤器的初始化操作
 * 5.我们可以给当前的Runner类设置一个IOC容器的属性，然后通过setApplicationContext方法来注入这个ioc容器
 *
 * @author Yanxinhao on 2025/2/7
 */
@Slf4j
//@Component
public class DistriBloomFilterInitRunner implements ApplicationRunner , ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        //1.获取SearchServiceImpl这个Bean对象
        SearchServiceImpl searchServiceImpl = applicationContext.getBean("searchServiceImpl", SearchServiceImpl.class);

        //2.获取RBloomFilter这个Bean对象
        RBloomFilter bloomFilter = applicationContext.getBean("bloomFilter", RBloomFilter.class);

        //3.通过searchServiceImpl对象执行获取专辑id集合的方法，获取专辑id集合，然后给布隆过滤器初始化赋值
        List<Long> albumIdList = searchServiceImpl.getAlbumIdList();

        //4.初始化布隆过滤器
        if (!CollectionUtils.isEmpty(albumIdList)){
            for (Long id : albumIdList) {
                bloomFilter.add(id);
            }
        }
        log.info("分布式布隆过滤器初始化完毕，内部id数量个数：" + bloomFilter.count());

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}